package com.zatech.cgnci.project.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zatech.cgnci.project.base.constant.ClaimConstant;
import com.zatech.cgnci.project.base.context.UserContext;
import com.zatech.cgnci.project.base.enums.*;
import com.zatech.cgnci.project.base.exception.GlobalException;
import com.zatech.cgnci.project.base.utils.ConvertUtils;
import com.zatech.cgnci.project.base.utils.VerifyUtils;
import com.zatech.cgnci.project.dto.*;
import com.zatech.cgnci.project.entity.*;
import com.zatech.cgnci.project.mapper.*;
import com.zatech.cgnci.project.service.*;
import com.zatech.cgnci.project.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 分入结算主表-任务 服务实现类
 * </p>
 *
 * @author Generator
 * @since 2024-12-25
 */
@Service
@Slf4j
public class CgnciClaimSettlementTaskServiceImpl extends ServiceImpl<CgnciClaimSettlementTaskMapper, CgnciClaimSettlementTaskDO> implements CgnciClaimSettlementTaskService {

    @Resource
    private CgnciClaimSettlementReinsurerTaskMapper reinsurerTaskMapper;
    @Resource
    private CgnciClaimSettlementReinsurerMapper reinsurerMapper;
    @Resource
    private CgnciClaimSettlementDetailTaskMapper detailTaskMapper;
    @Resource
    private CgnciClaimSettlementDetailMapper detailMapper;
    @Resource
    private CgnciClaimCaseService cgnciClaimCaseService;
    @Resource
    private CgnciClaimCaseTaskMapper cgnciClaimCaseTaskMapper;
    @Resource
    private IApprovalService approvalService;
    @Resource
    private CgnciBusinessInsuranceService policyService;
    @Resource
    private CgnciAccessoryService accessoryService;
    @Resource
    private CgnciClaimPolicyTaskMapper claimPolicyTaskMapper;
    @Resource
    private CgnciAccessoryMapper cgnciAccessoryMapper;
    @Autowired
    private CgnciClaimSettlementMapper claimSettlementMapper;
    @Autowired
    private CgnciClaimSettlementTaskMapper claimSettlementTaskMapper;
    @Autowired
    private CgnciClaimSettlementReinsurerTaskMapper settlementReinsurerTaskMapper;
    @Autowired
    private CgnciClaimSettlementDetailTaskMapper settlementDetailTaskMapper;
    @Autowired
    private CgnciClaimReserveMapper reserveMapper;
    @Autowired
    private CgnciClaimReserveDetailMapper reserveDetailMapper;
    @Autowired
    private CgnciClaimReserveTaskMapper reserveTaskMapper;
    @Autowired
    private CgnciClaimReserveDetailTaskMapper reserveDetailTaskMapper;
    @Autowired
    private CgnciApprovalInfoMapper approvalInfoMapper;
    @Autowired
    private CgnciCodeTypeService cgnciCodeTypeService;
    @Autowired
    private CgnciApprovalConfigMapper approvalConfigMapper;
    @Autowired
    private CgnciClaimCaseMapper cgnciClaimCaseMapper;
    @Autowired
    private CgnciOperationLogsService cgnciOperationLogsService;
    @Autowired
    private CgnciClaimAlertInfoService cgnciClaimAlertInfoService;
    @Autowired
    private CgnciProportionalLiabilityInvoiceService invoiceService;
    @Autowired
    private CgnciClaimReserveService claimReserveService;
    @Autowired
    private CgnciClaimSettlementService claimSettlementService;
    @Autowired
    private CgnciClaimReserveHistoryService claimReserveHistoryService;
    @Autowired
    private CgnciClaimSettlementReinsurerTaskService cgnciClaimSettlementReinsurerTaskService;
    @Autowired
    private CgnciClaimSettlementDetailTaskMapper cgnciClaimSettlementDetailTaskMapper;
    @Autowired
    private CgnciClaimSettlementDetailMapper cgnciClaimSettlementDetailMapper;


    @Override
    public List<CgnciClaimSettlementVO> settlementTaskListByBusinessNo(String businessNo) {
        LambdaQueryWrapper<CgnciClaimSettlementTaskDO> query = new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>()
                .eq(CgnciClaimSettlementTaskDO::getTaskBusinessNo, businessNo)
                .orderByDesc(CgnciClaimSettlementTaskDO::getSettlementNo);
        List<CgnciClaimSettlementTaskDO> settlementTaskList = getBaseMapper().selectList(query);
        if (CollectionUtils.isEmpty(settlementTaskList)) return new ArrayList<>();
        List<CgnciClaimSettlementVO> list = new ArrayList<>();
        for (CgnciClaimSettlementTaskDO item : settlementTaskList) {
            list.add(getClaimSettlementTaskVO(item));
        }
        return list;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CgnciClaimSettlementResultVO createSavePrepay(CgnciClaimSettlementDTO req) {
        createSaveCheck(req);
        CgnciClaimSettlementResultVO result = new CgnciClaimSettlementResultVO();
        Long settlementId = req.getSettlementId();
        // 第一次保存，插入结算信息
        if (VerifyUtils.isEmpty(settlementId)) {
            createSettlement(req, result, ClaimSettlementTypeEnum.PREPAYMENT.getCode());
            return result;
        }

        // 没有提交任务，更新结算信息
        if (VerifyUtils.isEmpty(req.getTaskNo())) {
            saveSettlement(req, result, ClaimSettlementTypeEnum.PREPAYMENT.getCode());
            return result;
        }

        // 更新我的案件和我的任务的结算信息
        saveSettlement(req, result, ClaimSettlementTypeEnum.PREPAYMENT.getCode());
        saveSettlementTask(req, result, ClaimSettlementTypeEnum.PREPAYMENT.getCode());

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CgnciClaimSettlementResultVO createSaveSettlement(CgnciClaimSettlementDTO req) {
        createSaveCheck(req);
        CgnciClaimSettlementResultVO result = new CgnciClaimSettlementResultVO();
        Long settlementId = req.getSettlementId();
        // 第一次保存，插入结算信息
        if (VerifyUtils.isEmpty(settlementId)) {
            createSettlement(req, result, ClaimSettlementTypeEnum.FINAL.getCode());
            return result;
        }

        // 没有提交任务，更新结算信息
        if (VerifyUtils.isEmpty(req.getTaskNo())) {
            saveSettlement(req, result, ClaimSettlementTypeEnum.FINAL.getCode());
            return result;
        }

        // 更新我的案件和我的任务的结算信息
        saveSettlement(req, result, ClaimSettlementTypeEnum.FINAL.getCode());
        saveSettlementTask(req, result, ClaimSettlementTypeEnum.FINAL.getCode());

        return result;
    }

    @Override
    public CgnciClaimSettlementResultVO submitSettlement(CgnciClaimSettlementSubmitDTO req) {
        CgnciClaimSettlementResultVO resultVO = submitValid(req);
        UserEntity user = UserContext.getUser();
        String caseNo = req.getCaseNo();
        String settlementNo = req.getSettlementNo();
        CgnciClaimSettlementTaskDO settlement = getSettlementTask(caseNo, settlementNo, req.getTaskType());
        if (Objects.nonNull(settlement) && ClaimTaskStatusEnum.CHECKING.getCode().equals(settlement.getTaskStatus())) {
            throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, settlement.getTaskNo() + "任务审核中，请勿再次提交。");
        }
        if (Objects.isNull(settlement)) {
            return firstSubmit(user, req, resultVO);  // 首次提交
        } else {
            FlowTaskSubmitDTO flowTask = new FlowTaskSubmitDTO();  // 二次提交
            flowTask.setFormId(settlement.getTaskNo());
            approvalService.submit(flowTask);
            updateCaseAndSettlementTaskStatus(user, settlement, ClaimTaskStatusEnum.CHECKING.getCode(),
                    null, Boolean.TRUE); // 更新任务状态
            String msg = null;
            if (StringUtils.isNotBlank(resultVO.getRemarks())) {
                msg = resultVO.getRemarks();
            }
            if (ClaimTaskTypeEnum.PREPAY.getCode().equals(req.getTaskType())) {
                saveLog(caseNo, OperationTypeEnum.SUBMIT_PREPAY, user.getUsername(), msg);
            } else if (ClaimTaskTypeEnum.CLOSE.getCode().equals(req.getTaskType())) {
                saveLog(caseNo, OperationTypeEnum.SUBMIT_CASE_FINAL, user.getUsername());
            }
            resultVO.setPolicyNo(settlement.getPolicyNo());
            resultVO.setCaseNo(settlement.getCaseNo());
            resultVO.setTaskNo(settlement.getTaskNo());
            resultVO.setSettlementNo(settlement.getSettlementNo());
            return resultVO;
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveSettlement(CgnciClaimCaseCheckDTO req) {
        UserEntity user = UserContext.getUser();
        String taskNo = req.getTaskNo();
        CgnciClaimSettlementTaskDO settlementTask = getSettlementTaskByTaskNo(taskNo);
        Assert.notNull(settlementTask, StringUtils.join(taskNo, "查询不到该任务。"));
        if (!ClaimTaskStatusEnum.CHECKING.getCode().equals(settlementTask.getTaskStatus())) {
            throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, "任务状态错误,不在审核中.");
        }
        String caseNo = settlementTask.getCaseNo();
        String msg = req.getReviewComments();
        FlowTaskApprovalDTO flowTask = new FlowTaskApprovalDTO();
        flowTask.setFormId(taskNo);
        flowTask.setFormNo(taskNo);
        flowTask.setApproverOpinions(req.getReviewComments());
        FlowTaskVO approve = approvalService.approve(flowTask);
        updateCaseAndSettlementTaskStatus(user, settlementTask, approve.getStatus(), req.getReviewComments(), Boolean.TRUE);
        if (ClaimSettlementTypeEnum.PREPAYMENT.getCode().equals(settlementTask.getSettlementType())) {
            saveLog(caseNo, OperationTypeEnum.PREPAY_TASK_PASS, user.getUsername(), msg);
            //新增临分摊赔账单数据
            if (ClaimTaskStatusEnum.DONE.getCode().equals(approve.getStatus())) {
                // TODO 抵扣准备金，准备金历史表插入一条预付结算数据，最新准备金扣减
                // 1.查询当前案件的准备金信息
                CgnciClaimReserveVO reserveVO = claimReserveService.detail(caseNo);
                if (VerifyUtils.isNotEmpty(reserveVO)) {
                    List<CgnciClaimReserveVO.ReserveDetailVO> details = reserveVO.getDetails();
                    if (VerifyUtils.isNotEmpty(details)) {
                        CgnciClaimSettlementTaskDO settlementTaskDO = this.getOne(new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>()
                                .eq(CgnciClaimSettlementTaskDO::getCaseNo, caseNo)
                                .eq(CgnciClaimSettlementTaskDO::getTaskNo, taskNo)
                                .eq(CgnciClaimSettlementTaskDO::getSettlementType, ClaimSettlementTypeEnum.PREPAYMENT.getCode()));
                        // 获取所有分人再保人
                        List<CgnciClaimSettlementReinsurerTaskDO> reinsurerTaskDOS = cgnciClaimSettlementReinsurerTaskService.list(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerTaskDO>()
                                        .eq(CgnciClaimSettlementReinsurerTaskDO::getSettlementId, settlementTaskDO.getSettlementId())
                                //.eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerType, ClaimReinsurerTypeEnum.CEDING.getCode())
                        );
                        List<Long> reinsurerIds = reinsurerTaskDOS.stream().map(CgnciClaimSettlementReinsurerTaskDO::getReinsurerId).collect(Collectors.toList());
                        // 获取所有分人再保人结算明细
                        List<CgnciClaimSettlementDetailTaskDO> detailDOList = cgnciClaimSettlementDetailTaskMapper.selectList(new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                                .in(CgnciClaimSettlementDetailTaskDO::getReinsurerId, reinsurerIds));

                        // 匹配出需要更新的准备金明细
                        details.forEach(reserveDetail -> {
                            // 根据险种过滤
                            List<CgnciClaimSettlementDetailTaskDO> riskTypeDetailDOList = detailDOList.stream().filter(detail -> reserveDetail.getRiskType().equals(detail.getRiskType())).collect(Collectors.toList());
                            // 结算金额(结算币种)汇总
                            BigDecimal inwardTotalSettlementAmount = riskTypeDetailDOList.stream().filter(detail -> "INWARD".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                            // 结算金额(原始币种)汇总
                            BigDecimal inwardTotalOriginalAmount = riskTypeDetailDOList.stream().filter(detail -> "INWARD".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmountOriginal).reduce(BigDecimal.ZERO, BigDecimal::add);

                            // 结算金额(结算币种)汇总
                            BigDecimal recoveryTotalSettlementAmount = riskTypeDetailDOList.stream().filter(detail -> "RECOVERY".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                            // 结算金额(原始币种)汇总
                            BigDecimal recoveryTotalOriginalAmount = riskTypeDetailDOList.stream().filter(detail -> "RECOVERY".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmountOriginal).reduce(BigDecimal.ZERO, BigDecimal::add);


                            // 准备金历史插入数据
                            CgnciClaimReserveHistoryDO reserveHistoryDO = new CgnciClaimReserveHistoryDO();
                            reserveHistoryDO.setCaseNo(caseNo);
                            reserveHistoryDO.setTaskNo(taskNo);
                            reserveHistoryDO.setTaskType(ClaimTaskTypeEnum.PREPAY.getCode());
                            reserveHistoryDO.setTaskStatus(ClaimTaskStatusEnum.DONE.getCode());
                            reserveHistoryDO.setRiskType(reserveDetail.getRiskType());
                            reserveHistoryDO.setRiskTypeName(reserveDetail.getRiskTypeName());
                            reserveHistoryDO.setSettlementCurrency(reserveDetail.getSettlementCurrency());
                            reserveHistoryDO.setApprovedReserve(reserveDetail.getAfterAdjustReserve());
                            BigDecimal totalSettlementAmount = inwardTotalSettlementAmount.subtract(recoveryTotalSettlementAmount);
                            reserveHistoryDO.setAdjustReserve(BigDecimal.ZERO.subtract(totalSettlementAmount));
                            reserveHistoryDO.setAfterAdjustReserve(reserveHistoryDO.getApprovedReserve().subtract(totalSettlementAmount).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : reserveHistoryDO.getApprovedReserve().subtract(totalSettlementAmount));
                            reserveHistoryDO.setOriginalCurrency(reserveDetail.getOriginalCurrency());
                            reserveHistoryDO.setApprovedReserveOriginal(reserveDetail.getAfterAdjustReserveOriginal());
                            BigDecimal totalOriginalAmount = inwardTotalOriginalAmount.subtract(recoveryTotalOriginalAmount);
                            reserveHistoryDO.setAdjustReserveOriginal(BigDecimal.ZERO.subtract(totalOriginalAmount));
                            reserveHistoryDO.setAfterAdjustReserveOriginal(reserveHistoryDO.getApprovedReserveOriginal().subtract(totalOriginalAmount).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : reserveHistoryDO.getApprovedReserveOriginal().subtract(totalOriginalAmount));
                            reserveHistoryDO.setRemark(req.getReviewComments());
                            reserveHistoryDO.setCreator(settlementTaskDO.getCreator());
                            reserveHistoryDO.setUpdater(user.getUsername());
                            claimReserveHistoryService.save(reserveHistoryDO);

                            // 最新准备金扣减
                            CgnciClaimReserveDetailDO detailDO = ConvertUtils.convert(reserveDetail, CgnciClaimReserveDetailDO.class);
                            detailDO.setApprovedReserve(reserveHistoryDO.getAfterAdjustReserve());
                            detailDO.setAdjustReserve(BigDecimal.ZERO);
                            detailDO.setAfterAdjustReserve(reserveHistoryDO.getAfterAdjustReserve());
                            detailDO.setApprovedReserveOriginal(reserveHistoryDO.getAfterAdjustReserveOriginal());
                            detailDO.setAdjustReserveOriginal(BigDecimal.ZERO);
                            detailDO.setAfterAdjustReserveOriginal(reserveHistoryDO.getAfterAdjustReserveOriginal());

                            detailDO.setBeforeSettlementReserve(reserveHistoryDO.getApprovedReserve());
                            detailDO.setSettlementReserve(reserveHistoryDO.getAdjustReserve());
                            detailDO.setAfterSettlementReserve(reserveHistoryDO.getAfterAdjustReserve());
                            detailDO.setBeforeOriginalReserve(reserveHistoryDO.getApprovedReserveOriginal());
                            detailDO.setOriginalReserve(reserveHistoryDO.getAdjustReserveOriginal());
                            detailDO.setAfterOriginalReserve(reserveHistoryDO.getAfterAdjustReserveOriginal());
                            reserveDetailMapper.updateById(detailDO);
                        });
                    }
                }

                invoiceService.insertClaimSettlement(caseNo, ClaimSettlementTypeEnum.PREPAYMENT.getCode());
            }
        } else if (ClaimSettlementTypeEnum.FINAL.getCode().equals(settlementTask.getSettlementType())) {
            freshCloseAmount(user, settlementTask, approve.getStatus());
            saveLog(caseNo, OperationTypeEnum.CASE_FINAL_TASK_PASS, user.getUsername(), msg);
            //新增临分摊赔账单数据
            if (ClaimTaskStatusEnum.DONE.getCode().equals(approve.getStatus())) {
                // TODO 清零准备金，准备金历史插入一条案件结算数据，最新准备金扣减
                // 1.查询当前案件的准备金信息
                CgnciClaimReserveVO reserveVO = claimReserveService.detail(caseNo);
                if (VerifyUtils.isNotEmpty(reserveVO)) {
                    List<CgnciClaimReserveVO.ReserveDetailVO> details = reserveVO.getDetails();
                    if (VerifyUtils.isNotEmpty(details)) {
                        CgnciClaimSettlementTaskDO settlementTaskDO = this.getOne(new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>()
                                .eq(CgnciClaimSettlementTaskDO::getCaseNo, caseNo)
                                .eq(CgnciClaimSettlementTaskDO::getTaskNo, taskNo)
                                .eq(CgnciClaimSettlementTaskDO::getSettlementType, ClaimSettlementTypeEnum.FINAL.getCode()));
                        // 获取所有分人再保人
                        List<CgnciClaimSettlementReinsurerTaskDO> reinsurerTaskDOS = cgnciClaimSettlementReinsurerTaskService.list(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerTaskDO>()
                                        .eq(CgnciClaimSettlementReinsurerTaskDO::getSettlementId, settlementTaskDO.getSettlementId())
                                //.eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerType, ClaimReinsurerTypeEnum.CEDING.getCode())
                        );
                        List<Long> reinsurerIds = reinsurerTaskDOS.stream().map(CgnciClaimSettlementReinsurerTaskDO::getReinsurerId).collect(Collectors.toList());
                        // 获取所有分人再保人结算明细
                        List<CgnciClaimSettlementDetailTaskDO> detailDOList = cgnciClaimSettlementDetailTaskMapper.selectList(new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                                .in(CgnciClaimSettlementDetailTaskDO::getReinsurerId, reinsurerIds));

                        // 匹配出需要更新的准备金明细
                        details.forEach(reserveDetail -> {
                            // 根据险种过滤
                            List<CgnciClaimSettlementDetailTaskDO> riskTypeDetailDOList = detailDOList.stream().filter(detail -> reserveDetail.getRiskType().equals(detail.getRiskType())).collect(Collectors.toList());
                            // 结算金额(结算币种)汇总
                            BigDecimal inwardTotalSettlementAmount = riskTypeDetailDOList.stream().filter(detail -> "INWARD".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                            // 结算金额(原始币种)汇总
                            BigDecimal inwardTotalOriginalAmount = riskTypeDetailDOList.stream().filter(detail -> "INWARD".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmountOriginal).reduce(BigDecimal.ZERO, BigDecimal::add);

                            // 结算金额(结算币种)汇总
                            BigDecimal recoveryTotalSettlementAmount = riskTypeDetailDOList.stream().filter(detail -> "RECOVERY".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                            // 结算金额(原始币种)汇总
                            BigDecimal recoveryTotalOriginalAmount = riskTypeDetailDOList.stream().filter(detail -> "RECOVERY".equals(detail.getDetailType())).map(CgnciClaimSettlementDetailTaskDO::getSettlementAmountOriginal).reduce(BigDecimal.ZERO, BigDecimal::add);


                            // 准备金历史插入数据
                            CgnciClaimReserveHistoryDO reserveHistoryDO = new CgnciClaimReserveHistoryDO();
                            reserveHistoryDO.setCaseNo(caseNo);
                            reserveHistoryDO.setTaskNo(taskNo);
                            reserveHistoryDO.setTaskType(ClaimTaskTypeEnum.CLOSE.getCode());
                            reserveHistoryDO.setTaskStatus(ClaimTaskStatusEnum.DONE.getCode());
                            reserveHistoryDO.setRiskType(reserveDetail.getRiskType());
                            reserveHistoryDO.setRiskTypeName(reserveDetail.getRiskTypeName());
                            reserveHistoryDO.setSettlementCurrency(reserveDetail.getSettlementCurrency());
                            reserveHistoryDO.setApprovedReserve(reserveDetail.getAfterAdjustReserve());
                            BigDecimal totalSettlementAmount = inwardTotalSettlementAmount.subtract(recoveryTotalSettlementAmount);
                            reserveHistoryDO.setAdjustReserve(BigDecimal.ZERO.subtract(totalSettlementAmount));
                            reserveHistoryDO.setAfterAdjustReserve(reserveHistoryDO.getApprovedReserve().subtract(totalSettlementAmount).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : reserveHistoryDO.getApprovedReserve().subtract(totalSettlementAmount));
                            reserveHistoryDO.setOriginalCurrency(reserveDetail.getOriginalCurrency());
                            reserveHistoryDO.setApprovedReserveOriginal(reserveDetail.getAfterAdjustReserveOriginal());
                            BigDecimal totalOriginalAmount = inwardTotalOriginalAmount.subtract(recoveryTotalOriginalAmount);
                            reserveHistoryDO.setAdjustReserveOriginal(BigDecimal.ZERO.subtract(totalOriginalAmount));
                            reserveHistoryDO.setAfterAdjustReserveOriginal(reserveHistoryDO.getApprovedReserveOriginal().subtract(totalOriginalAmount).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : reserveHistoryDO.getApprovedReserveOriginal().subtract(totalOriginalAmount));
                            reserveHistoryDO.setRemark(req.getReviewComments());
                            reserveHistoryDO.setCreator(settlementTaskDO.getCreator());
                            reserveHistoryDO.setUpdater(user.getUsername());
                            claimReserveHistoryService.save(reserveHistoryDO);

                            // 最新准备金扣减
                            CgnciClaimReserveDetailDO detailDO = ConvertUtils.convert(reserveDetail, CgnciClaimReserveDetailDO.class);
                            detailDO.setApprovedReserve(reserveHistoryDO.getAfterAdjustReserve());
                            detailDO.setAdjustReserve(BigDecimal.ZERO);
                            detailDO.setAfterAdjustReserve(reserveHistoryDO.getAfterAdjustReserve());
                            detailDO.setApprovedReserveOriginal(reserveHistoryDO.getAfterAdjustReserveOriginal());
                            detailDO.setAdjustReserveOriginal(BigDecimal.ZERO);
                            detailDO.setAfterAdjustReserveOriginal(reserveHistoryDO.getAfterAdjustReserveOriginal());

                            detailDO.setBeforeSettlementReserve(reserveHistoryDO.getApprovedReserve());
                            detailDO.setSettlementReserve(reserveHistoryDO.getAdjustReserve());
                            detailDO.setAfterSettlementReserve(reserveHistoryDO.getAfterAdjustReserve());
                            detailDO.setBeforeOriginalReserve(reserveHistoryDO.getApprovedReserveOriginal());
                            detailDO.setOriginalReserve(reserveHistoryDO.getAdjustReserveOriginal());
                            detailDO.setAfterOriginalReserve(reserveHistoryDO.getAfterAdjustReserveOriginal());
                            reserveDetailMapper.updateById(detailDO);
                        });
                    }
                }

                invoiceService.insertClaimSettlement(caseNo, ClaimSettlementTypeEnum.FINAL.getCode());
            }
        }
    }


    @Override
    public void logOffCase(String taskNo) {
        CgnciClaimSettlementTaskDO settlementTask = getSettlementTaskByTaskNo(taskNo);
        if (!ClaimTaskStatusEnum.BACK.getCode().equals(settlementTask.getTaskStatus())) {
            throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, "非退回状态，不能注销。");
        }
        String caseNo = settlementTask.getCaseNo();
        UserEntity user = UserContext.getUser();
        FlowTaskCancelDTO flowTask = new FlowTaskCancelDTO();
        flowTask.setFormId(taskNo);
        flowTask.setFormNo(taskNo);
        approvalService.cancelTask(flowTask);
        updateCaseAndSettlementTaskStatus(user, settlementTask, ClaimTaskStatusEnum.LOG_OFF.getCode(), null, Boolean.FALSE);
        // 物理删除案件结算数据
        LambdaQueryWrapper<CgnciClaimSettlementDO> query = new LambdaQueryWrapper<CgnciClaimSettlementDO>()
                .eq(CgnciClaimSettlementDO::getCaseNo, settlementTask.getCaseNo())
                .eq(CgnciClaimSettlementDO::getSettlementNo, settlementTask.getSettlementNo())
                .eq(CgnciClaimSettlementDO::getSettlementType, settlementTask.getSettlementType());
        List<CgnciClaimSettlementDO> settlementTaskList = claimSettlementMapper.selectList(query);
        CgnciClaimSettlementDO settlementTaskDO = settlementTaskList.get(0);
        Long settlementId = settlementTaskDO.getSettlementId();
        claimSettlementMapper.deleteById(settlementId);
        LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO> queryReinsurer =
                new LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO>()
                        .eq(CgnciClaimSettlementReinsurerDO::getSettlementId, settlementId);
        List<CgnciClaimSettlementReinsurerDO> reinsList = reinsurerMapper.selectList(queryReinsurer);
        List<Long> reinsIds = reinsList.stream().map(CgnciClaimSettlementReinsurerDO::getReinsurerId).collect(Collectors.toList());
        if (VerifyUtils.isNotEmpty(reinsIds)) {
            reinsurerMapper.deleteBatchIds(reinsIds);
        }
        LambdaQueryWrapper<CgnciClaimSettlementDetailDO> delParam =
                new LambdaQueryWrapper<CgnciClaimSettlementDetailDO>()
                        .in(CgnciClaimSettlementDetailDO::getReinsurerId, reinsIds);
        detailMapper.delete(delParam);
        if (ClaimSettlementTypeEnum.PREPAYMENT.getCode().equals(settlementTask.getSettlementType())) {
            saveLog(caseNo, OperationTypeEnum.CANCEL_PREPAY, user.getUsername());
        } else if (ClaimSettlementTypeEnum.FINAL.getCode().equals(settlementTask.getSettlementType())) {
            saveLog(caseNo, OperationTypeEnum.CANCEL_CASE_FINAL, user.getUsername());
        }
    }

    @Override
    public void delSettlement(Long settlementId) {
        CgnciClaimSettlementDO settlementDO = claimSettlementMapper.selectById(settlementId);
        if (Objects.isNull(settlementDO)) return;
        boolean input = ClaimTaskStatusEnum.INPUT.getCode().equals(settlementDO.getTaskStatus());
        Assert.isTrue(input, "非录入中，不可删除。");
        claimSettlementMapper.deleteById(settlementId);
        // 删除再保人
        LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO> queryReinsurer =
                new LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO>()
                        .eq(CgnciClaimSettlementReinsurerDO::getSettlementId, settlementId);
        List<CgnciClaimSettlementReinsurerDO> reinsList = reinsurerMapper.selectList(queryReinsurer);
        List<Long> reinsIds = reinsList.stream().map(CgnciClaimSettlementReinsurerDO::getReinsurerId).collect(Collectors.toList());
        reinsurerMapper.deleteBatchIds(reinsIds);
        // 删除再保人明细
        LambdaQueryWrapper<CgnciClaimSettlementDetailDO> delParam =
                new LambdaQueryWrapper<CgnciClaimSettlementDetailDO>()
                        .in(CgnciClaimSettlementDetailDO::getReinsurerId, reinsIds);
        detailMapper.delete(delParam);
    }

    @Override
    public void createCheck(String caseNo, String settlementType) {
        LambdaQueryWrapper<CgnciClaimSettlementDO> condition = new LambdaQueryWrapper<CgnciClaimSettlementDO>()
                .eq(CgnciClaimSettlementDO::getCaseNo, caseNo)
                .eq(CgnciClaimSettlementDO::getSettlementType, settlementType);
        List<CgnciClaimSettlementDO> settlementDOList = claimSettlementMapper.selectList(condition);
        if (CollectionUtils.isNotEmpty(settlementDOList)) {
            CgnciClaimSettlementDO cgnciClaimSettlementDO = settlementDOList.stream().filter(e ->
                    ClaimTaskStatusEnum.INPUT.getCode().equals(e.getTaskStatus())
                            || ClaimTaskStatusEnum.BACK.getCode().equals(e.getTaskStatus())).findAny().orElse(null);
            Assert.isNull(cgnciClaimSettlementDO, "请勿重复创建预付申请/结算申请。");

            /*if (VerifyUtils.isNotEmpty(cgnciClaimSettlementDO)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "请勿重复创建预付申请/结算申请。");
            }*/

            LambdaQueryWrapper<CgnciClaimCaseTaskDO> param = new LambdaQueryWrapper<CgnciClaimCaseTaskDO>()
                    .eq(CgnciClaimCaseTaskDO::getCaseNo, caseNo)
                    .notIn(CgnciClaimCaseTaskDO::getTaskStatus, Arrays.asList(ClaimTaskStatusEnum.LOG_OFF.getCode(), ClaimTaskStatusEnum.DONE.getCode()));
            Integer count = cgnciClaimCaseTaskMapper.selectCount(param);
            Assert.isTrue(count < 1, "您有未处理完毕的任务，无法再次发起新任务。");

        }

    }

    @Override
    public Boolean submitCheck(SettlementQueryDTO req) {
        CgnciClaimSettlementVO claimSettlementVO = claimSettlementService.settlementQuery(SettlementQueryDTO.builder()
                .caseNo(req.getCaseNo()).settlementNo(req.getSettlementNo())
                .settlementType("4".equals(req.getTaskType()) ? "PREPAYMENT" : "FINAL").build());
        List<CgnciClaimSettlementVO.ReinsurerVO> intoSettlementList = claimSettlementVO.getIntoSettlementList();
        // 汇总
        BigDecimal intoSettlementAmount = com.zatech.cgnci.project.base.utils.BeanUtils.sumBigDecimalProperty(intoSettlementList, CgnciClaimSettlementVO.ReinsurerVO::getTotalSettlementAmount);


        List<CgnciClaimSettlementVO.ReinsurerVO> spreadBackSettlementList = claimSettlementVO.getSpreadBackSettlementList();
        // 汇总
        BigDecimal spreadBackSettlementAmount = com.zatech.cgnci.project.base.utils.BeanUtils.sumBigDecimalProperty(spreadBackSettlementList, CgnciClaimSettlementVO.ReinsurerVO::getTotalSettlementAmount);

        return spreadBackSettlementAmount.compareTo(intoSettlementAmount) > 0;
    }

    @Override
    public void backSettlement(CgnciClaimCaseCheckDTO req) {
        UserEntity user = UserContext.getUser();
        String taskNo = req.getTaskNo();
        CgnciClaimSettlementTaskDO settlementTask = getSettlementTaskByTaskNo(taskNo);
        String caseNo = settlementTask.getCaseNo();
        FlowTaskBackDTO flowTask = new FlowTaskBackDTO();
        // 需要指定退回节点
        flowTask.setApprovalNode(req.getApprovalNode());
        flowTask.setFormId(taskNo);
        flowTask.setFormNo(taskNo);
        // 当前处理人
        flowTask.setApproverOpinions(req.getReviewComments());
        FlowTaskVO back = approvalService.back(flowTask);
        updateCaseAndSettlementTaskStatus(user, settlementTask, back.getStatus(),
                req.getReviewComments(), Boolean.TRUE);
        String msg = req.getReviewComments();
        if (ClaimSettlementTypeEnum.PREPAYMENT.getCode().equals(settlementTask.getSettlementType())) {
            saveLog(caseNo, OperationTypeEnum.PREPAY_TASK_BACK, user.getUsername(), msg);
        } else if (ClaimSettlementTypeEnum.FINAL.getCode().equals(settlementTask.getSettlementType())) {
            saveLog(caseNo, OperationTypeEnum.CASE_FINAL_TASK_BACK, user.getUsername(), msg);
        }
    }

    @Override
    public void delSettlementDetail(CgnciClaimDelDTO req) {
        if ("1".equals(req.getSourceType())) {
            req.getDetailIdList().forEach(detailId -> {

                CgnciClaimSettlementDetailDO detailDO = detailMapper.selectById(detailId);
                if (VerifyUtils.isEmpty(detailDO)) {
                    return;
                }
                detailMapper.deleteById(detailId);

                // 查询再保人
                CgnciClaimSettlementReinsurerDO reinsurerDO = reinsurerMapper.selectById(detailDO.getReinsurerId());
                if (VerifyUtils.isEmpty(reinsurerDO)) {
                    return;
                }

                // 查询结案表
                CgnciClaimSettlementDO settlementDO = claimSettlementMapper.selectById(reinsurerDO.getSettlementId());
                if (VerifyUtils.isEmpty(settlementDO.getTaskNo())) {
                    return;
                }

                // 删除我的任务-再保人-详情
                CgnciClaimSettlementDetailTaskDO detailTaskDO = detailTaskMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                        .eq(CgnciClaimSettlementDetailTaskDO::getCaseNo, settlementDO.getCaseNo())
                        .eq(CgnciClaimSettlementDetailTaskDO::getTaskNo, settlementDO.getTaskNo())
                        .eq(CgnciClaimSettlementDetailTaskDO::getDetailType, detailDO.getDetailType())
                        .eq(CgnciClaimSettlementDetailTaskDO::getRiskType, detailDO.getRiskType())
                        .eq(CgnciClaimSettlementDetailTaskDO::getSubjectName, detailDO.getSubjectName()));
                if (VerifyUtils.isNotEmpty(detailTaskDO)) {
                    detailTaskMapper.deleteById(detailTaskDO.getDetailId());
                }
            });

        } else {
            req.getDetailIdList().forEach(detailId -> {

                CgnciClaimSettlementDetailTaskDO detailTaskDO = detailTaskMapper.selectById(detailId);
                if (VerifyUtils.isEmpty(detailTaskDO)) {
                    throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, "明细不存在");
                }
                detailTaskMapper.deleteById(detailId);

                CgnciClaimSettlementReinsurerTaskDO reinsurerTaskDO = reinsurerTaskMapper.selectById(detailTaskDO.getReinsurerId());

                // 查询结案表
                CgnciClaimSettlementDO settlementDO = claimSettlementMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementDO>()
                        .eq(CgnciClaimSettlementDO::getCaseNo, detailTaskDO.getCaseNo())
                        .eq(CgnciClaimSettlementDO::getTaskNo, detailTaskDO.getTaskNo()));
                if (VerifyUtils.isEmpty(settlementDO.getTaskNo())) {
                    return;
                }

                // 查询再保人
                CgnciClaimSettlementReinsurerDO reinsurerDO = reinsurerMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO>()
                        .eq(CgnciClaimSettlementReinsurerDO::getSettlementId, settlementDO.getSettlementId())
                        .eq(CgnciClaimSettlementReinsurerDO::getCaseNo, detailTaskDO.getCaseNo())
                        .eq(CgnciClaimSettlementReinsurerDO::getReinsurerType, reinsurerTaskDO.getReinsurerType()));
                if (VerifyUtils.isEmpty(reinsurerDO)) {
                    return;
                }

                // 删除我的任务-再保人-详情
                CgnciClaimSettlementDetailDO detailDO = detailMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementDetailDO>()
                        .eq(CgnciClaimSettlementDetailDO::getCaseNo, detailTaskDO.getCaseNo())
                        .eq(CgnciClaimSettlementDetailDO::getDetailType, detailTaskDO.getDetailType())
                        .eq(CgnciClaimSettlementDetailDO::getRiskType, detailTaskDO.getRiskType())
                        .eq(CgnciClaimSettlementDetailDO::getSubjectName, detailTaskDO.getSubjectName()));
                if (VerifyUtils.isNotEmpty(detailDO)) {
                    detailMapper.deleteById(detailDO.getDetailId());
                }
            });
        }
    }

    @Override
    public void delSettlementReinsurer(Long reinsurerId, String sourceType) {
        if ("1".equals(sourceType)) {
            // 删除我的案件-再保人
            CgnciClaimSettlementReinsurerDO reinsurerDO = reinsurerMapper.selectById(reinsurerId);
            if (VerifyUtils.isEmpty(reinsurerDO)) {
                return;
            }
            reinsurerMapper.deleteById(reinsurerId);

            // 删除我的案件-再保人-详情
            LambdaQueryWrapper<CgnciClaimSettlementDetailDO> delParam =
                    new LambdaQueryWrapper<CgnciClaimSettlementDetailDO>()
                            .eq(CgnciClaimSettlementDetailDO::getReinsurerId, reinsurerId);
            detailMapper.delete(delParam);


            // 查询结案表
            CgnciClaimSettlementDO settlementDO = claimSettlementMapper.selectById(reinsurerDO.getSettlementId());
            if (VerifyUtils.isEmpty(settlementDO.getTaskNo())) {
                return;
            }
            // 删除我的任务-再保人
            CgnciClaimSettlementReinsurerTaskDO reinsurerTaskDO = reinsurerTaskMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerTaskDO>()
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getCaseNo, reinsurerDO.getCaseNo())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getTaskNo, settlementDO.getTaskNo())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerType, reinsurerDO.getReinsurerType())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerName, reinsurerDO.getReinsurerName())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerRowKey, reinsurerDO.getReinsurerRowKey()));
            reinsurerTaskMapper.deleteById(reinsurerTaskDO.getReinsurerId());

            // 删除我的案件-再保人-详情
            LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO> delTaskParam =
                    new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                            .eq(CgnciClaimSettlementDetailTaskDO::getReinsurerId, reinsurerTaskDO.getReinsurerId());
            detailTaskMapper.delete(delTaskParam);
        } else {
            // 删除我的任务-再保人
            CgnciClaimSettlementReinsurerTaskDO reinsurerTaskDO = reinsurerTaskMapper.selectById(reinsurerId);
            if (VerifyUtils.isEmpty(reinsurerTaskDO)) {
                throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "再保人不存在。");
            }
            reinsurerTaskMapper.deleteById(reinsurerId);

            // 删除我的案件-再保人-详情
            LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO> delTaskParam =
                    new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                            .eq(CgnciClaimSettlementDetailTaskDO::getReinsurerId, reinsurerId);
            detailTaskMapper.delete(delTaskParam);

            // 查询结案表
            CgnciClaimSettlementDO settlementDO = claimSettlementMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementDO>()
                    .eq(CgnciClaimSettlementDO::getCaseNo, reinsurerTaskDO.getCaseNo())
                    .eq(CgnciClaimSettlementDO::getTaskNo, reinsurerTaskDO.getTaskNo()));
            if (VerifyUtils.isEmpty(settlementDO.getTaskNo())) {
                return;
            }

            // 删除我的案件-再保人
            CgnciClaimSettlementReinsurerDO reinsurerDO = reinsurerMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO>()
                    .eq(CgnciClaimSettlementReinsurerDO::getSettlementId, settlementDO.getSettlementId())
                    .eq(CgnciClaimSettlementReinsurerDO::getCaseNo, reinsurerTaskDO.getCaseNo())
                    .eq(CgnciClaimSettlementReinsurerDO::getReinsurerType, reinsurerTaskDO.getReinsurerType())
                    .eq(CgnciClaimSettlementReinsurerDO::getReinsurerName, reinsurerTaskDO.getReinsurerName())
                    .eq(CgnciClaimSettlementReinsurerDO::getReinsurerRowKey, reinsurerTaskDO.getReinsurerRowKey()));
            reinsurerMapper.deleteById(reinsurerDO.getReinsurerId());

            // 删除我的案件-再保人-详情
            LambdaQueryWrapper<CgnciClaimSettlementDetailDO> delParam =
                    new LambdaQueryWrapper<CgnciClaimSettlementDetailDO>()
                            .eq(CgnciClaimSettlementDetailDO::getReinsurerId, reinsurerDO.getReinsurerId());
            detailMapper.delete(delParam);
        }


    }

    @Override
    public List<ApprovalConfigVO> listBackNode(String taskNo) {
        CgnciApprovalInfoDO approvalInfo = approvalInfoMapper.selectOne(new LambdaQueryWrapper<CgnciApprovalInfoDO>()
                .eq(CgnciApprovalInfoDO::getFormId, taskNo)
                .eq(CgnciApprovalInfoDO::getFormNo, taskNo));
        if (VerifyUtils.isEmpty(approvalInfo)) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "任务不存在");
        }
        // 获取指定分组,小于某节点的所有节点
        List<CgnciApprovalConfigDO> CgnciApprovalConfigDOList = approvalConfigMapper.selectList(
                new LambdaQueryWrapper<CgnciApprovalConfigDO>()
                        .eq(CgnciApprovalConfigDO::getGroupId, approvalInfo.getApprovalConfigGroupId())
                        .lt(CgnciApprovalConfigDO::getApprovalNode, approvalInfo.getApprovalNode())
                        .orderByDesc(CgnciApprovalConfigDO::getApprovalNode));
        return ConvertUtils.convert(CgnciApprovalConfigDOList, ApprovalConfigVO.class);
    }


    private void saveSettlement(CgnciClaimSettlementDTO req, CgnciClaimSettlementResultVO result, String settlementType) {
        // ClaimSettlementTypeEnum.PREPAYMENT.getCode()
        Assert.hasText(req.getCaseNo(), "立案号必填。");
        Assert.hasText(req.getSettlementNo(), "结算号必填");
        UserEntity user = UserContext.getUser();
        CgnciClaimSettlementDO settlement = querySettlement(req.getCaseNo(), req.getTaskNo(), req.getSettlementNo(), settlementType);
        CgnciClaimSettlementDO update = ConvertUtils.convert(req, CgnciClaimSettlementDO.class);
        if (Objects.nonNull(req.getExtra())) {
            update.setExtra(JSON.toJSONString(req.getExtra()));
        }
        update.setTaskNo(null); // 不更新任务号
        update.setSettlementType(null); // 不更结算类型
        update.setSettlementId(settlement.getSettlementId());
        claimSettlementMapper.updateById(update);
        settlement.setTaskNo(null);
        saveReinsurerAndDetail(user, settlement, req);
        result.setCaseNo(settlement.getCaseNo());
        result.setSettlementNo(settlement.getSettlementNo());
    }

    private void saveSettlementTask(CgnciClaimSettlementDTO req, CgnciClaimSettlementResultVO result, String settlementType) {
        // ClaimSettlementTypeEnum.PREPAYMENT.getCode()
        Assert.hasText(req.getCaseNo(), "立案号必填。");
        Assert.hasText(req.getSettlementNo(), "结算号必填");
        UserEntity user = UserContext.getUser();
        CgnciClaimSettlementTaskDO settlementTask = querySettlementTask(req.getCaseNo(), req.getTaskNo(), req.getSettlementNo(), settlementType);
        CgnciClaimSettlementTaskDO update = ConvertUtils.convert(req, CgnciClaimSettlementTaskDO.class);
        if (Objects.nonNull(req.getExtra())) {
            update.setExtra(JSON.toJSONString(req.getExtra()));
        }
        update.setTaskNo(null); // 不更新任务号
        update.setSettlementType(null); // 不更结算类型
        update.setSettlementId(settlementTask.getSettlementId());
        claimSettlementTaskMapper.updateById(update);
        settlementTask.setTaskNo(null);
        saveReinsurerAndDetailTask(user, settlementTask, req);
        result.setCaseNo(settlementTask.getCaseNo());
        result.setSettlementNo(settlementTask.getSettlementNo());
    }

    private CgnciClaimSettlementDO querySettlement(String caseNo, String taskNo, String settlementNo, String settlementType) {
        LambdaQueryWrapper<CgnciClaimSettlementDO> query = new LambdaQueryWrapper<CgnciClaimSettlementDO>()
                .eq(CgnciClaimSettlementDO::getCaseNo, caseNo)
                .eq(VerifyUtils.isNotEmpty(taskNo), CgnciClaimSettlementDO::getTaskNo, taskNo)
                .eq(CgnciClaimSettlementDO::getSettlementNo, settlementNo)
                .eq(CgnciClaimSettlementDO::getSettlementType, settlementType);
        CgnciClaimSettlementDO settlementDO = claimSettlementMapper.selectOne(query);
        Assert.notNull(settlementDO, StringUtils.join(caseNo, "-", settlementNo, "查询不到结算数据"));
        return settlementDO;
    }

    private CgnciClaimSettlementTaskDO querySettlementTask(String caseNo, String taskNo, String settlementNo, String settlementType) {
        LambdaQueryWrapper<CgnciClaimSettlementTaskDO> query = new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>()
                .eq(CgnciClaimSettlementTaskDO::getCaseNo, caseNo)
                .eq(CgnciClaimSettlementTaskDO::getTaskNo, taskNo)
                .eq(CgnciClaimSettlementTaskDO::getSettlementNo, settlementNo)
                .eq(CgnciClaimSettlementTaskDO::getSettlementType, settlementType);
        CgnciClaimSettlementTaskDO settlementTaskDO = claimSettlementTaskMapper.selectOne(query);
        Assert.notNull(settlementTaskDO, StringUtils.join(caseNo, "-", settlementNo, "查询不到结算数据"));
        return settlementTaskDO;
    }

    private CgnciClaimSettlementTaskDO getSettlementTaskByTaskNo(String taskNo) {
        LambdaQueryWrapper<CgnciClaimSettlementTaskDO> query = new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>()
                .eq(CgnciClaimSettlementTaskDO::getTaskNo, taskNo);
        CgnciClaimSettlementTaskDO settlementTaskDO = this.getBaseMapper().selectOne(query);
        Assert.notNull(settlementTaskDO, StringUtils.join(taskNo, "查询不到结算数据"));
        return settlementTaskDO;
    }

    private void createPrepayCheck(CgnciClaimSettlementDTO req) {
        LambdaQueryWrapper<CgnciClaimCaseTaskDO> param = new LambdaQueryWrapper<CgnciClaimCaseTaskDO>()
                .eq(CgnciClaimCaseTaskDO::getCaseNo, req.getCaseNo())
                .notIn(CgnciClaimCaseTaskDO::getTaskStatus, Arrays.asList(ClaimTaskStatusEnum.LOG_OFF.getCode(), ClaimTaskStatusEnum.DONE.getCode()));
        Integer count = cgnciClaimCaseTaskMapper.selectCount(param);
        Assert.isTrue(count < 1, "您有未处理完毕的任务，无法再次发起新任务。");

        /*if (count > 0) {
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, "您有未处理完毕的任务，无法再次发起新任务。");
        }*/
    }

    private void createSettlement(CgnciClaimSettlementDTO req, CgnciClaimSettlementResultVO result, String settlementType) {
        String caseNo = req.getCaseNo();
        StopWatch sw = new StopWatch();
        sw.start("createPrepayCheck");
        createPrepayCheck(req);
        sw.stop();
        UserEntity user = UserContext.getUser();
        sw.start("getMaxSettlementNo");
        String maxNo = getMaxSettlementNo(req, settlementType);
        sw.stop();
        // save new data
        CgnciClaimSettlementDO settlement = ConvertUtils.convert(req, CgnciClaimSettlementDO.class);
        settlement.setTaskNo(null); // 避免前端误传
        settlement.setSettlementNo(maxNo);
        settlement.setSettlementType(settlementType);
        settlement.setCaseNo(caseNo);
        settlement.setCreator(user.getNameAndCode());
        settlement.setUpdater(user.getNameAndCode());
        settlement.setTaskStatus(ClaimTaskStatusEnum.INPUT.getCode());
        if (Objects.nonNull(req.getExtra())) {
            settlement.setExtra(JSON.toJSONString(req.getExtra()));
        }
        claimSettlementMapper.insert(settlement);
        sw.start("saveReinsurerAndDetail");
        saveReinsurerAndDetail(user, settlement, req);
        sw.stop();
        result.setCaseNo(settlement.getCaseNo());
        result.setSettlementNo(settlement.getSettlementNo());
        log.debug("预付申请创建createPrepay 总耗时：{} 耗时详情：{}", sw.getTotalTimeSeconds(), sw.prettyPrint());
    }

    private ApprovalInfoVO createCaseFlow(UserEntity user, CgnciClaimCaseTaskDO task, String flowGroupId) {
        FlowTaskCreateDTO flowTask = new FlowTaskCreateDTO();
        flowTask.setApprovalConfigGroupId(flowGroupId);
        flowTask.setFormId(task.getTaskNo());
        flowTask.setFormNo(task.getTaskNo());
        return approvalService.create(flowTask);
    }

    private String getMaxSettlementNo(CgnciClaimSettlementDTO req, String settlementType) {
        String number = claimSettlementMapper.selectMaxSettlementNo(req.getCaseNo(), settlementType);
        if (Objects.isNull(number)) {
            return ClaimConstant.STR_ZERO_ZERO_ONE;
        } else {
            int integer = Integer.parseInt(number);
            integer += 1;
            if (integer < 10) {
                return StringUtils.join(ClaimConstant.STR_ZERO_ZERO, integer);
            } else if (integer < 100) {
                return StringUtils.join(ClaimConstant.STR_ZERO, integer);
            }
            return Integer.toString(integer);
        }
    }

    private CgnciClaimCaseTaskDO copyCreateCaseTask(UserEntity user, String caseNo, String settlementNo, String taskType) {
        StopWatch sw = new StopWatch();
        sw.start("copyCreateCaseTask");
        CgnciClaimCaseVO caseDetail = cgnciClaimCaseService.detail(caseNo);
        sw.stop();
        sw.start("cgnciClaimCaseTaskMapper.insert");
        CgnciClaimCaseTaskDO caseTask = ConvertUtils.convert(caseDetail, CgnciClaimCaseTaskDO.class);
        caseTask.setCaseId(null);
        caseTask.setTaskNo(generateTaskNo());
        caseTask.setCreator(user.getNameAndCode());
        caseTask.setUpdater(user.getNameAndCode());
        caseTask.setTaskType(taskType);
        caseTask.setTaskStatus(ClaimTaskStatusEnum.CHECKING.getCode());
        cgnciClaimCaseTaskMapper.insert(caseTask);
        sw.stop();
        sw.start("copySaveCasePolicyInfo");
        copySaveCasePolicyInfo(caseTask);
        sw.stop();
        sw.start("copySaveReserve");
        copySaveReserve(caseTask);
        sw.stop();
        sw.start("copySaveSettlement");
        copySaveSettlement(caseDetail, caseTask);
        sw.stop();
        sw.start("copySaveAttachment");
        copySaveAttachment(caseDetail, caseTask);
        sw.stop();
        log.debug("复制创建copyCreateCaseTask 总耗时：{} 耗时详情：{}", sw.getTotalTimeSeconds(), sw.prettyPrint());
        // 更新案件结算任务状态
//        updateSettlementStatus(user, caseNo, settlementNo, caseTask.getTaskNo(), ClaimTaskStatusEnum.CHECKING.getCode());
        CgnciClaimSettlementTaskDO settlement = new CgnciClaimSettlementTaskDO();
        settlement.setSettlementNo(settlementNo);
        settlement.setCaseNo(caseNo);
        settlement.setTaskNo(caseTask.getTaskNo());
        if (ClaimTaskTypeEnum.PREPAY.getCode().equals(taskType)) {
            settlement.setSettlementType(ClaimSettlementTypeEnum.PREPAYMENT.getCode());
        } else if (ClaimTaskTypeEnum.CLOSE.getCode().equals(taskType)) {
            settlement.setSettlementType(ClaimSettlementTypeEnum.FINAL.getCode());
        }
        updateCaseAndSettlementTaskStatus(user, settlement, ClaimTaskStatusEnum.CHECKING.getCode(), null, Boolean.TRUE);
        return caseTask;
    }

    private void saveReinsurerAndDetail(UserEntity user, CgnciClaimSettlementDO settlement,
                                        CgnciClaimSettlementDTO req) {
        Long settlementId = settlement.getSettlementId();
        String caseNo = settlement.getCaseNo();
        List<CgnciClaimSettlementVO.ReinsurerVO> allOfSettlementList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(req.getIntoSettlementList())) {
            req.getIntoSettlementList().forEach(e -> e.setReinsurerType(ClaimReinsurerTypeEnum.CEDING.getCode()));
            allOfSettlementList.addAll(req.getIntoSettlementList());
        }
        if (CollectionUtils.isNotEmpty(req.getSpreadBackSettlementList())) {
            req.getSpreadBackSettlementList().forEach(e -> e.setReinsurerType(ClaimReinsurerTypeEnum.ACCEPTOR.getCode()));
            allOfSettlementList.addAll(req.getSpreadBackSettlementList());
        }
        if (CollectionUtils.isEmpty(allOfSettlementList)) return;
        for (CgnciClaimSettlementVO.ReinsurerVO reins : allOfSettlementList) {
            // 保存再保人
            CgnciClaimSettlementReinsurerDO reinsurerDO = ConvertUtils.convert(reins, CgnciClaimSettlementReinsurerDO.class);
            reinsurerDO.setSettlementId(settlementId);

            // 查询再保人是否存在
            CgnciClaimSettlementReinsurerDO isReinsurerDO = reinsurerMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerDO>()
                    .eq(CgnciClaimSettlementReinsurerDO::getCaseNo, req.getCaseNo())
                    .eq(CgnciClaimSettlementReinsurerDO::getSettlementId, settlementId)
                    .eq(CgnciClaimSettlementReinsurerDO::getReinsurerType, reinsurerDO.getReinsurerType())
                    .eq(CgnciClaimSettlementReinsurerDO::getReinsurerName, reinsurerDO.getReinsurerName())
                    .eq(VerifyUtils.isNotEmpty(reinsurerDO.getReinsurerRowKey()), CgnciClaimSettlementReinsurerDO::getReinsurerRowKey, reinsurerDO.getReinsurerRowKey()));

            if (VerifyUtils.isEmpty(isReinsurerDO)) {
                reinsurerDO.setCaseNo(caseNo);
                reinsurerDO.setCreator(user.getNameAndCode());
                reinsurerDO.setUpdater(user.getNameAndCode());
                reinsurerMapper.insert(reinsurerDO);
            } else {
                reinsurerDO.setReinsurerId(isReinsurerDO.getReinsurerId());
                reinsurerDO.setUpdater(user.getNameAndCode());
                reinsurerDO.setUpdateTime(new Date());
                reinsurerMapper.updateById(reinsurerDO);
            }
            if (VerifyUtils.isNotEmpty(reins.getDetails())) {
                for (CgnciClaimSettlementVO.DetailVO detailVO : reins.getDetails()) {
                    CgnciClaimSettlementDetailDO detailDO = ConvertUtils.convert(detailVO, CgnciClaimSettlementDetailDO.class);
                    detailDO.setReinsurerId(reinsurerDO.getReinsurerId());
                    if (ClaimReinsurerTypeEnum.CEDING.getCode().equals(reinsurerDO.getReinsurerType())) {
                        detailDO.setDetailType(ClaimDetailTypeEnum.INWARD.getCode());
                    } else if (ClaimReinsurerTypeEnum.ACCEPTOR.getCode().equals(reinsurerDO.getReinsurerType())) {
                        detailDO.setDetailType(ClaimDetailTypeEnum.RECOVERY.getCode());
                    }

                    // 查询再保人结算明细是否存在
                    CgnciClaimSettlementDetailDO isReinsurerDetailDO = detailMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementDetailDO>()
                            .eq(CgnciClaimSettlementDetailDO::getCaseNo, req.getCaseNo())
                            .eq(CgnciClaimSettlementDetailDO::getReinsurerId, reinsurerDO.getReinsurerId())
                            .eq(CgnciClaimSettlementDetailDO::getRiskType, detailDO.getRiskType())
                            .eq(CgnciClaimSettlementDetailDO::getSubjectName, detailDO.getSubjectName()));

                    if (VerifyUtils.isEmpty(isReinsurerDetailDO)) {
                        detailDO.setCaseNo(caseNo);
                        detailDO.setCreator(user.getNameAndCode());
                        detailDO.setUpdater(user.getNameAndCode());
                        detailMapper.insert(detailDO);
                    } else {
                        detailDO.setDetailId(isReinsurerDetailDO.getDetailId());
                        detailDO.setUpdater(user.getNameAndCode());
                        detailDO.setUpdateTime(new Date());
                        detailMapper.updateById(detailDO);
                    }
                }
            }
        }
    }

    private void saveReinsurerAndDetailTask(UserEntity user, CgnciClaimSettlementTaskDO settlementTask, CgnciClaimSettlementDTO req) {
        Long settlementId = settlementTask.getSettlementId();
        String caseNo = settlementTask.getCaseNo();
        List<CgnciClaimSettlementVO.ReinsurerVO> allOfSettlementList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(req.getIntoSettlementList())) {
            req.getIntoSettlementList().forEach(e -> e.setReinsurerType(ClaimReinsurerTypeEnum.CEDING.getCode()));
            allOfSettlementList.addAll(req.getIntoSettlementList());
        }
        if (CollectionUtils.isNotEmpty(req.getSpreadBackSettlementList())) {
            req.getSpreadBackSettlementList().forEach(e -> e.setReinsurerType(ClaimReinsurerTypeEnum.ACCEPTOR.getCode()));
            allOfSettlementList.addAll(req.getSpreadBackSettlementList());
        }
        if (CollectionUtils.isEmpty(allOfSettlementList)) return;
        for (CgnciClaimSettlementVO.ReinsurerVO reins : allOfSettlementList) {
            // 保存再保人
            CgnciClaimSettlementReinsurerTaskDO reinsurerTaskDO = ConvertUtils.convert(reins, CgnciClaimSettlementReinsurerTaskDO.class);
            reinsurerTaskDO.setSettlementId(settlementId);

            // 查询再保人是否存在
            CgnciClaimSettlementReinsurerTaskDO isReinsurerTaskDO = reinsurerTaskMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementReinsurerTaskDO>()
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getCaseNo, req.getCaseNo())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getTaskNo, req.getTaskNo())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getSettlementId, settlementId)
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerType, reinsurerTaskDO.getReinsurerType())
                    .eq(CgnciClaimSettlementReinsurerTaskDO::getReinsurerName, reinsurerTaskDO.getReinsurerName())
                    .eq(VerifyUtils.isNotEmpty(reinsurerTaskDO.getReinsurerRowKey()), CgnciClaimSettlementReinsurerTaskDO::getReinsurerRowKey, reinsurerTaskDO.getReinsurerRowKey()));

            if (VerifyUtils.isEmpty(isReinsurerTaskDO)) {
                reinsurerTaskDO.setCaseNo(caseNo);
                reinsurerTaskDO.setTaskNo(req.getTaskNo());
                reinsurerTaskDO.setCreator(user.getNameAndCode());
                reinsurerTaskDO.setUpdater(user.getNameAndCode());
                reinsurerTaskMapper.insert(reinsurerTaskDO);
            } else {
                reinsurerTaskDO.setReinsurerId(isReinsurerTaskDO.getReinsurerId());
                reinsurerTaskDO.setUpdater(user.getNameAndCode());
                reinsurerTaskDO.setUpdateTime(new Date());
                reinsurerTaskMapper.updateById(reinsurerTaskDO);
            }
            if (VerifyUtils.isNotEmpty(reins.getDetails())) {
                for (CgnciClaimSettlementVO.DetailVO detailVO : reins.getDetails()) {
                    CgnciClaimSettlementDetailTaskDO detailTaskDO = ConvertUtils.convert(detailVO, CgnciClaimSettlementDetailTaskDO.class);
                    detailTaskDO.setReinsurerId(reinsurerTaskDO.getReinsurerId());
                    if (ClaimReinsurerTypeEnum.CEDING.getCode().equals(reinsurerTaskDO.getReinsurerType())) {
                        detailTaskDO.setDetailType(ClaimDetailTypeEnum.INWARD.getCode());
                    } else if (ClaimReinsurerTypeEnum.ACCEPTOR.getCode().equals(reinsurerTaskDO.getReinsurerType())) {
                        detailTaskDO.setDetailType(ClaimDetailTypeEnum.RECOVERY.getCode());
                    }

                    // 查询再保人结算明细是否存在
                    CgnciClaimSettlementDetailTaskDO isReinsurerDetailTaskDO = detailTaskMapper.selectOne(new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                            .eq(CgnciClaimSettlementDetailTaskDO::getCaseNo, req.getCaseNo())
                            .eq(CgnciClaimSettlementDetailTaskDO::getTaskNo, req.getTaskNo())
                            .eq(CgnciClaimSettlementDetailTaskDO::getReinsurerId, reinsurerTaskDO.getReinsurerId())
                            .eq(CgnciClaimSettlementDetailTaskDO::getRiskType, detailTaskDO.getRiskType())
                            .eq(CgnciClaimSettlementDetailTaskDO::getSubjectName, detailTaskDO.getSubjectName()));


                    if (VerifyUtils.isEmpty(isReinsurerDetailTaskDO)) {
                        detailTaskDO.setCaseNo(caseNo);
                        detailTaskDO.setTaskNo(req.getTaskNo());
                        detailTaskDO.setCreator(user.getNameAndCode());
                        detailTaskDO.setUpdater(user.getNameAndCode());
                        detailTaskMapper.insert(detailTaskDO);
                    } else {
                        detailTaskDO.setDetailId(isReinsurerDetailTaskDO.getDetailId());
                        detailTaskDO.setUpdater(user.getNameAndCode());
                        detailTaskDO.setUpdateTime(new Date());
                        detailTaskMapper.updateById(detailTaskDO);
                    }
                }
            }
        }
    }


    private void copySaveReserve(CgnciClaimCaseTaskDO caseTask) {
        String caseNo = caseTask.getCaseNo();
        String taskNo = caseTask.getTaskNo();
        LambdaQueryWrapper<CgnciClaimReserveDO> query = new LambdaQueryWrapper<CgnciClaimReserveDO>()
                .eq(CgnciClaimReserveDO::getCaseNo, caseNo);
        List<CgnciClaimReserveDO> reserveDOS = reserveMapper.selectList(query);
        if (CollectionUtils.isEmpty(reserveDOS)) return;
        for (CgnciClaimReserveDO reserve : reserveDOS) {
            CgnciClaimReserveTaskDO reserveTaskDO = ConvertUtils.convert(reserve, CgnciClaimReserveTaskDO.class);
            reserveTaskDO.setReserveId(null);
            reserveTaskDO.setTaskNo(taskNo);
            reserveTaskDO.setCreator(caseTask.getCreator());
            reserveTaskDO.setUpdater(caseTask.getUpdater());
            reserveTaskMapper.insert(reserveTaskDO);
            saveReserveDetail(taskNo, reserve, reserveTaskDO);
        }
    }


    private void saveReserveDetail(String taskNo, CgnciClaimReserveDO reserve, CgnciClaimReserveTaskDO reserveTaskDO) {
        LambdaQueryWrapper<CgnciClaimReserveDetailDO> queryDetail = new LambdaQueryWrapper<CgnciClaimReserveDetailDO>()
                .eq(CgnciClaimReserveDetailDO::getReserveId, reserve.getReserveId());
        List<CgnciClaimReserveDetailDO> reserveDetailDOS = reserveDetailMapper.selectList(queryDetail);
        if (CollectionUtils.isEmpty(reserveDetailDOS)) return;
        for (CgnciClaimReserveDetailDO reserveDetail : reserveDetailDOS) {
            CgnciClaimReserveDetailTaskDO detailTaskDO = ConvertUtils.convert(reserveDetail, CgnciClaimReserveDetailTaskDO.class);
            detailTaskDO.setDetailId(null);
            detailTaskDO.setReserveId(reserveTaskDO.getReserveId());
            detailTaskDO.setTaskNo(taskNo);
            detailTaskDO.setCreator(reserveTaskDO.getCreator());
            detailTaskDO.setUpdater(reserveTaskDO.getUpdater());
            reserveDetailTaskMapper.insert(detailTaskDO);
        }
    }

    private void copySaveSettlement(CgnciClaimCaseVO caseDetail, CgnciClaimCaseTaskDO caseTask) {
        String caseNo = caseTask.getCaseNo();
        String businessNo = caseNo + caseTask.getTaskNo();
        if (CollectionUtils.isEmpty(caseDetail.getSettlements())) return;
        for (CgnciClaimSettlementVO settlement : caseDetail.getSettlements()) {
            CgnciClaimSettlementTaskDO settlementTask = ConvertUtils.convert(settlement, CgnciClaimSettlementTaskDO.class);
            settlementTask.setSettlementId(null);
            if (StringUtils.isBlank(settlement.getTaskNo())) {
                settlementTask.setTaskNo(caseTask.getTaskNo());
            } else {
                settlementTask.setTaskNo(settlement.getTaskNo());
            }
            settlementTask.setTaskBusinessNo(businessNo);
            settlementTask.setCaseNo(caseNo);
            settlementTask.setCreator(caseTask.getCreator());
            settlementTask.setUpdater(caseTask.getUpdater());
            claimSettlementTaskMapper.insert(settlementTask);
            copySaveReinsurer(settlement, settlementTask);
        }
    }

    private void copySaveReinsurer(CgnciClaimSettlementVO settlementVO, CgnciClaimSettlementTaskDO settlementTask) {
        Long settlementId = settlementTask.getSettlementId();
        String taskNo = settlementTask.getTaskNo();
        String caseNo = settlementTask.getCaseNo();
        List<CgnciClaimSettlementVO.ReinsurerVO> allList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(settlementVO.getIntoSettlementList())) {
            allList.addAll(settlementVO.getIntoSettlementList());
        }
        if (CollectionUtils.isNotEmpty(settlementVO.getSpreadBackSettlementList())) {
            allList.addAll(settlementVO.getSpreadBackSettlementList());
        }
        if (CollectionUtils.isNotEmpty(allList)) {
            for (CgnciClaimSettlementVO.ReinsurerVO reinsurerVO : allList) {
                CgnciClaimSettlementReinsurerTaskDO reinsurerDO = ConvertUtils.convert(reinsurerVO,
                        CgnciClaimSettlementReinsurerTaskDO.class);
                reinsurerDO.setReinsurerId(null);
                reinsurerDO.setCaseNo(caseNo);
                reinsurerDO.setTaskNo(taskNo);
                reinsurerDO.setCreator(settlementTask.getCreator());
                reinsurerDO.setUpdater(settlementTask.getUpdater());
                reinsurerDO.setSettlementId(settlementId);
                settlementReinsurerTaskMapper.insert(reinsurerDO);
                if (CollectionUtils.isEmpty(reinsurerVO.getDetails())) continue;
                for (CgnciClaimSettlementVO.DetailVO detail : reinsurerVO.getDetails()) {
                    CgnciClaimSettlementDetailTaskDO detailTaskDO = new CgnciClaimSettlementDetailTaskDO();
                    BeanUtils.copyProperties(detail, detailTaskDO);
                    detailTaskDO.setDetailId(null);
                    detailTaskDO.setCaseNo(caseNo);
                    detailTaskDO.setTaskNo(taskNo);
                    detailTaskDO.setCreator(settlementTask.getCreator());
                    detailTaskDO.setUpdater(settlementTask.getUpdater());
                    detailTaskDO.setReinsurerId(reinsurerDO.getReinsurerId());
                    settlementDetailTaskMapper.insert(detailTaskDO);
                }
            }
        }

    }

    private void copySaveAttachment(CgnciClaimCaseVO caseDetail, CgnciClaimCaseTaskDO caseTask) {
        if (CollectionUtils.isEmpty(caseDetail.getAccessoryList())) return;
        List<CgnciAccessoryDO> accessoryList = ConvertUtils.convert(caseDetail.getAccessoryList(), CgnciAccessoryDO.class);
        for (CgnciAccessoryDO accessory : accessoryList) {
            accessory.setAccId(null);
            accessory.setUploadNode("claim-task");
            accessory.setBusinessNo(caseTask.getTaskNo());
            accessory.setBusinessId(caseTask.getCaseId());
            accessory.setCreateUser(caseTask.getCreator());
            accessory.setUpdateUser(caseTask.getUpdater());
            accessory.setCreateTime(new Date());
            accessory.setUpdateTime(new Date());
            cgnciAccessoryMapper.insert(accessory);
        }


    }

    private void copySaveCasePolicyInfo(CgnciClaimCaseTaskDO task) {
        String policyNo = task.getPolicyNo();
        CgnciClaimPolicyTaskDO claimPolicyDO = claimPolicyTaskMapper.selectOne(
                new LambdaQueryWrapper<CgnciClaimPolicyTaskDO>()
                        .eq(CgnciClaimPolicyTaskDO::getTaskNo, task.getTaskNo()));
        CgnciBusinessInsuranceMainVO policyInfo = policyService.getPolicyInfo(policyNo);
        if (policyInfo == null || Objects.isNull(policyInfo.getBusinessInsuranceVO())) {
            return;
        }
        CgnciClaimPolicyTaskDO claimPolicy = new CgnciClaimPolicyTaskDO();
        CgnciBusinessInsuranceVO bizInsuranceVO = policyInfo.getBusinessInsuranceVO();
        claimPolicy.setTaskNo(task.getTaskNo());
        claimPolicy.setCurrentPolicyId(bizInsuranceVO.getInsuranceId());
        claimPolicy.setCaseNo(task.getCaseNo());
        claimPolicy.setPolicyNo(policyNo);
        claimPolicy.setRiskSubType(bizInsuranceVO.getRiskSubType());
        claimPolicy.setRiskSubTypeCode(bizInsuranceVO.getRiskSubTypeCode());
        claimPolicy.setProjectName(bizInsuranceVO.getProjectName());
        claimPolicy.setProjectNo(bizInsuranceVO.getProjectNo());
        claimPolicy.setCedingCompany(policyInfo.getReinsurers());
        claimPolicy.setAcceptCompany(policyInfo.getAcceptCompany());
        if (VerifyUtils.isNotEmpty(policyInfo.getStatVOList())) {
            claimPolicy.setShareRatio(policyInfo.getStatVOList().get(0).getShareRatio());
            claimPolicy.setCededRatio(policyInfo.getStatVOList().get(0).getCededRatio());
            claimPolicy.setNetSelfShare(policyInfo.getStatVOList().get(0).getRetentionRatio());
        }
        if (Objects.equals(Boolean.TRUE, policyInfo.getIsDivideOut())) {
            claimPolicy.setReinsureFlag(YesOrNoEnum.YES.getCode());
        } else {
            claimPolicy.setReinsureFlag(YesOrNoEnum.NO.getCode());
        }
        claimPolicy.setPolicyStartDate(policyInfo.getBusinessInsuranceVO().getStartDate());
        claimPolicy.setPolicyEndDate(policyInfo.getBusinessInsuranceVO().getEndDate());
        claimPolicy.setPolicyYear(policyInfo.getBusinessInsuranceVO().getBusinessYear());
        claimPolicy.setPolicyCurrency(policyInfo.getBusinessInsuranceVO().getCurrency());
        if (Objects.isNull(claimPolicyDO)) {
            claimPolicy.setCreator(task.getCreator());
            claimPolicy.setUpdater(task.getUpdater());
            claimPolicyTaskMapper.insert(claimPolicy);
        } else {
            claimPolicy.setId(claimPolicyDO.getId());
            claimPolicy.setUpdateTime(new Date());
            claimPolicyTaskMapper.updateById(claimPolicy);
        }
    }


    private String generateTaskNo() {
        CgnciCodeTypeDO cgnciCodeTypeDO = cgnciCodeTypeService.getOne(new LambdaQueryWrapper<CgnciCodeTypeDO>()
                .eq(CgnciCodeTypeDO::getCodeHigherLevelCode, "claims-task")
                .eq(CgnciCodeTypeDO::getCodeName, "number"));
        String codeCode = cgnciCodeTypeDO.getCodeCode();
        int nextCodeCode = Integer.parseInt(codeCode) + 1;
        cgnciCodeTypeDO.setCodeCode(String.valueOf(nextCodeCode));
        cgnciCodeTypeService.updateById(cgnciCodeTypeDO);
        return StringUtils.join(ClaimConstant.T, nextCodeCode);
    }


    private CgnciClaimSettlementVO getClaimSettlementTaskVO(CgnciClaimSettlementTaskDO params) {
        CgnciClaimSettlementVO claimSettlementVO = new CgnciClaimSettlementVO();
        BeanUtils.copyProperties(params, claimSettlementVO);
        if (StringUtils.isNotBlank(params.getExtra())) {
            claimSettlementVO.setExtra(JSONObject.parseObject(params.getExtra()));
        }
        List<CgnciClaimSettlementVO.ReinsurerVO> intoSettlementReinsurerList = new ArrayList<>();
        List<CgnciClaimSettlementVO.ReinsurerVO> outSettlementReinsurerList = new ArrayList<>();
        List<CgnciClaimSettlementReinsurerTaskDO> reinsurerList = reinsurerTaskMapper.selectList(
                new LambdaQueryWrapper<CgnciClaimSettlementReinsurerTaskDO>()
                        .eq(CgnciClaimSettlementReinsurerTaskDO::getTaskNo, params.getTaskNo())
                        .eq(CgnciClaimSettlementReinsurerTaskDO::getSettlementId, params.getSettlementId()));
        if (CollectionUtils.isEmpty(reinsurerList)) return null;
        List<CgnciClaimSettlementVO.ReinsurerVO> reinsurerVOList = ConvertUtils.convert(reinsurerList, CgnciClaimSettlementVO.ReinsurerVO.class);
        for (CgnciClaimSettlementVO.ReinsurerVO reinsurerVO : reinsurerVOList) {
            if (ClaimReinsurerTypeEnum.CEDING.getCode().equals(reinsurerVO.getReinsurerType())) {
                reinsurerVO.setDetails(getDetailByReinsurerId(reinsurerVO.getReinsurerId(), params.getTaskNo()));
                buildTotalSettlementAmount(reinsurerVO);
                intoSettlementReinsurerList.add(reinsurerVO);
            } else {
                reinsurerVO.setDetails(getDetailByReinsurerId(reinsurerVO.getReinsurerId(), params.getTaskNo()));
                buildTotalSettlementAmount(reinsurerVO);
                outSettlementReinsurerList.add(reinsurerVO);
            }
        }
        claimSettlementVO.setIntoSettlementList(intoSettlementReinsurerList);
        claimSettlementVO.setSpreadBackSettlementList(outSettlementReinsurerList);
        return claimSettlementVO;
    }

    private void buildTotalSettlementAmount(CgnciClaimSettlementVO.ReinsurerVO reinsurer) {
        if (Objects.nonNull(reinsurer) && CollectionUtils.isNotEmpty(reinsurer.getDetails())) {
            BigDecimal amount = BigDecimal.ZERO;
            BigDecimal amountOriginal = BigDecimal.ZERO;
            for (CgnciClaimSettlementVO.DetailVO detail : reinsurer.getDetails()) {
                if (Objects.nonNull(detail.getSettlementAmount())) {
                    amount = amount.add(detail.getSettlementAmount());
                }
                if (Objects.nonNull(detail.getSettlementAmountOriginal())) {
                    amountOriginal = amount.add(detail.getSettlementAmountOriginal());
                }
            }
            reinsurer.setTotalSettlementAmount(amount);
            reinsurer.setTotalSettlementAmountOriginal(amountOriginal);
        }
    }

    private List<CgnciClaimSettlementVO.DetailVO> getDetailByReinsurerId(Long reinsurerId, String TaskNo) {
        List<CgnciClaimSettlementDetailTaskDO> detailDOs = detailTaskMapper.selectList(
                new LambdaQueryWrapper<CgnciClaimSettlementDetailTaskDO>()
                        .eq(CgnciClaimSettlementDetailTaskDO::getTaskNo, TaskNo)
                        .eq(CgnciClaimSettlementDetailTaskDO::getReinsurerId, reinsurerId)
        );
        return ConvertUtils.convert(detailDOs, CgnciClaimSettlementVO.DetailVO.class);
    }


    private CgnciClaimSettlementTaskDO getSettlementTask(String caseNo, String settlementNo, String taskType) {
        String settlementType = null;
        if (ClaimTaskTypeEnum.PREPAY.getCode().equals(taskType)) {
            settlementType = ClaimSettlementTypeEnum.PREPAYMENT.getCode();
        } else if (ClaimTaskTypeEnum.CLOSE.getCode().equals(taskType)) {
            settlementType = ClaimSettlementTypeEnum.FINAL.getCode();
        }
        Assert.hasText(settlementType, "settlementType缺失。");
        LambdaQueryWrapper<CgnciClaimSettlementTaskDO> param = new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>()
                .eq(CgnciClaimSettlementTaskDO::getCaseNo, caseNo)
                .eq(CgnciClaimSettlementTaskDO::getSettlementType, settlementType)
                .eq(CgnciClaimSettlementTaskDO::getSettlementNo, settlementNo);
        return this.baseMapper.selectOne(param);
    }

    private void updateCaseAndSettlementTaskStatus(UserEntity user, CgnciClaimSettlementTaskDO settlementTask, String taskStatus,
                                                   String reviewComments, Boolean needSynData) {
        String taskNo = settlementTask.getTaskNo();
        LambdaQueryWrapper<CgnciClaimCaseTaskDO> condition = new LambdaQueryWrapper<CgnciClaimCaseTaskDO>().eq(CgnciClaimCaseTaskDO::getTaskNo, taskNo);
        //CgnciClaimCaseTaskDO updateCaseTask = new CgnciClaimCaseTaskDO();
        CgnciClaimCaseTaskDO updateCaseTask = cgnciClaimCaseTaskMapper.selectOne(condition);
        updateCaseTask.setTaskStatus(taskStatus);
        updateCaseTask.setUpdater(user.getNameAndCode());
        updateCaseTask.setUpdateTime(new Date());
        updateCaseTask.setReviewComments(reviewComments);

        // 审批通过，更新摊赔金额，公估费，总计金额
        if (ClaimTaskStatusEnum.DONE.getCode().equals(taskStatus)) {
            BigDecimal estimationAmount = VerifyUtils.isEmpty(updateCaseTask.getEstimationAmount()) ? BigDecimal.ZERO : updateCaseTask.getEstimationAmount();
            updateCaseTask.setEstimationAmount(estimationAmount.add(settlementTask.getEstimationAmount()));

            BigDecimal compensationAmount = VerifyUtils.isEmpty(updateCaseTask.getCompensationAmount()) ? BigDecimal.ZERO : updateCaseTask.getCompensationAmount();
            updateCaseTask.setCompensationAmount(compensationAmount.add(settlementTask.getCompensationAmount()));

            BigDecimal totalAmount = VerifyUtils.isEmpty(updateCaseTask.getTotalAmount()) ? BigDecimal.ZERO : updateCaseTask.getTotalAmount();
            updateCaseTask.setTotalAmount(totalAmount.add(settlementTask.getTotalAmount()));

        }
        if (ClaimTaskStatusEnum.DONE.getCode().equals(taskStatus) // update case status
                && ClaimSettlementTypeEnum.FINAL.getCode().equals(settlementTask.getSettlementType())) {
            updateCaseTask.setCaseStatus(ClaimCaseStatusEnum.CLOSE.getCode());
        }
        cgnciClaimCaseTaskMapper.updateById(updateCaseTask);

        LambdaQueryWrapper<CgnciClaimSettlementTaskDO> conditionSettle =
                new LambdaQueryWrapper<CgnciClaimSettlementTaskDO>().eq(CgnciClaimSettlementTaskDO::getTaskNo, taskNo);
        CgnciClaimSettlementTaskDO settlementTaskDO = new CgnciClaimSettlementTaskDO();
        settlementTaskDO.setTaskStatus(taskStatus);
        settlementTaskDO.setUpdater(user.getNameAndCode());
        settlementTaskDO.setUpdateTime(new Date());
        settlementTaskDO.setLatestAuditOpinion(reviewComments);
        this.baseMapper.update(settlementTaskDO, conditionSettle);
        // 同步更新案件
        if (Objects.equals(Boolean.TRUE, needSynData)) {
            CgnciClaimCaseTaskDO synParam = new CgnciClaimCaseTaskDO();
            synParam.setCaseNo(settlementTask.getCaseNo());
            synParam.setTaskNo(settlementTask.getTaskNo());
            synParam.setTaskStatus(updateCaseTask.getTaskStatus());
            synParam.setCaseStatus(updateCaseTask.getCaseStatus());
            settlementTask.setLatestAuditOpinion(reviewComments);
            synCaseAndSettlement(user, synParam, settlementTask);
        }
    }


    private void synCaseAndSettlement(UserEntity user, CgnciClaimCaseTaskDO caseTaskDO,
                                      CgnciClaimSettlementTaskDO settlementTask) {
        String settlementType = settlementTask.getSettlementType();
        String settlementNo = settlementTask.getSettlementNo();
        String caseNo = caseTaskDO.getCaseNo();
        String taskNo = caseTaskDO.getTaskNo();
        String taskStatus = caseTaskDO.getTaskStatus();
        String caseStatus = caseTaskDO.getCaseStatus();
        CgnciClaimSettlementDO updateSettle = new CgnciClaimSettlementDO();
        updateSettle.setTaskStatus(taskStatus);
        updateSettle.setUpdater(user.getNameAndCode());
        updateSettle.setUpdateTime(new Date());
        updateSettle.setTaskNo(taskNo);
        updateSettle.setLatestAuditOpinion(settlementTask.getLatestAuditOpinion());

        if (Objects.nonNull(caseStatus)) {
            cgnciClaimCaseMapper.updateCaseStatus(caseNo, caseStatus);
        }

        // 审批通过，更新摊赔金额，公估费，总计金额
        if (ClaimTaskStatusEnum.DONE.getCode().equals(taskStatus)) {
            LambdaQueryWrapper<CgnciClaimCaseDO> caseCondition = new LambdaQueryWrapper<CgnciClaimCaseDO>().eq(CgnciClaimCaseDO::getCaseNo, caseNo);
            CgnciClaimCaseDO claimCase = cgnciClaimCaseMapper.selectOne(caseCondition);
            BigDecimal estimationAmount = VerifyUtils.isEmpty(claimCase.getEstimationAmount()) ? BigDecimal.ZERO : claimCase.getEstimationAmount();
            claimCase.setEstimationAmount(estimationAmount.add(settlementTask.getEstimationAmount()));

            BigDecimal compensationAmount = VerifyUtils.isEmpty(claimCase.getCompensationAmount()) ? BigDecimal.ZERO : claimCase.getCompensationAmount();
            claimCase.setCompensationAmount(compensationAmount.add(settlementTask.getCompensationAmount()));

            BigDecimal totalAmount = VerifyUtils.isEmpty(claimCase.getTotalAmount()) ? BigDecimal.ZERO : claimCase.getTotalAmount();
            claimCase.setTotalAmount(totalAmount.add(settlementTask.getTotalAmount()));
            cgnciClaimCaseMapper.updateById(claimCase);
        }

        LambdaQueryWrapper<CgnciClaimSettlementDO> conditionSettle = new LambdaQueryWrapper<CgnciClaimSettlementDO>()
                .eq(CgnciClaimSettlementDO::getCaseNo, caseNo)
                .eq(CgnciClaimSettlementDO::getSettlementNo, settlementNo)
                .eq(CgnciClaimSettlementDO::getSettlementType, settlementType);
        String condition = StringUtils.join("caseNo:", caseNo, "settlementNo:", settlementNo, "settlementType", settlementType);
        log.info("{}更新结案数据,更新内容：{} 更新条件：{}", taskNo, JSON.toJSONString(updateSettle), condition);
        claimSettlementMapper.update(updateSettle, conditionSettle);
    }

    private void freshCloseAmount(UserEntity user, CgnciClaimSettlementTaskDO task, String taskStatus) {
        if (ClaimTaskStatusEnum.DONE.getCode().equals(taskStatus)
                && ClaimSettlementTypeEnum.FINAL.getCode().equals(task.getSettlementType())) {
            LambdaQueryWrapper<CgnciClaimCaseDO> condition = new LambdaQueryWrapper<CgnciClaimCaseDO>()
                    .eq(CgnciClaimCaseDO::getCaseNo, task.getCaseNo());
            CgnciClaimCaseDO updateCase = new CgnciClaimCaseDO();
            updateCase.setUpdater(user.getNameAndCode());
            updateCase.setUpdateTime(new Date());
            BigDecimal amount = detailMapper.selectSumSettlementAmount(task.getCaseNo());
            Date date = new Date();
            updateCase.setCloseTime(date);
            if (ClaimConstant.STR_ZERO_ZERO_ONE.equals(task.getSettlementNo())) {
                updateCase.setFirstCloseTime(date);
                updateCase.setFirstCloseAmount(amount);
                updateCase.setLatestCloseAmount(amount);
            } else {
                updateCase.setLatestCloseAmount(amount);
            }
            cgnciClaimCaseMapper.update(updateCase, condition);
        }
    }


    private void saveLog(String taskNo, OperationTypeEnum typeEnum, String creator, String... remarks) {
        Assert.notNull(typeEnum, "操作类型必填");
        CgnciOperationLogsDTO saveLog = new CgnciOperationLogsDTO();
        if (Objects.nonNull(remarks)) {
            String content = String.join(ClaimConstant.SEMICOLON, remarks);
            saveLog.setContent(content);
        }
        Date now = new Date();
        saveLog.setBizNo(taskNo);
        saveLog.setBizType(BusinessScenariosEnum.CLAIM.getCode());
        saveLog.setOperationType(typeEnum.getCode());
        saveLog.setCreateTime(now);
        saveLog.setCreator(creator);
        saveLog.setUpdateTime(now);
        saveLog.setUpdater(creator);
        cgnciOperationLogsService.saveLog(saveLog);
    }

    private void saveMessage(AlertInfoTypeEnum typeEnum, String caseNo, String content, String businessSceneType) {
        CgnciClaimAlertInfoDO info = new CgnciClaimAlertInfoDO();
        info.setContent(content);
        info.setBusinessNo(caseNo);
        info.setAlertType(typeEnum.getCode());
        info.setBusinessScene(BusinessScenariosEnum.CLAIM.getCode());
        info.setBusinessSceneType(businessSceneType);
        cgnciClaimAlertInfoService.clearHistoryAndSave(info);
    }

    private CgnciClaimSettlementResultVO submitValid(CgnciClaimSettlementSubmitDTO req) {
        CgnciClaimSettlementResultVO resultVO = new CgnciClaimSettlementResultVO();
        if (req.getConfirm()) {
            resultVO.setCaseNo(req.getCaseNo());
            return resultVO;
        }
        String caseNo = req.getCaseNo();

        CgnciClaimSettlementVO claimSettlementVO = claimSettlementService.settlementQuery(SettlementQueryDTO.builder()
                .caseNo(caseNo).settlementNo(req.getSettlementNo())
                .settlementType("4".equals(req.getTaskType()) ? "PREPAYMENT" : "FINAL").build());

        String businessSceneType = null;
        if (ClaimTaskTypeEnum.PREPAY.getCode().equals(req.getTaskType())) {
            businessSceneType = BusinessScenariosTypeEnum.CLAIM_PREPAYMENT.getCode();
        } else if (ClaimTaskTypeEnum.CLOSE.getCode().equals(req.getTaskType())) {
            businessSceneType = BusinessScenariosTypeEnum.CLAIM_FINAL.getCode();
        }
        List<String> noticeList = new ArrayList<>();
        List<CgnciClaimSettlementVO.ReinsurerVO> intoSettlementList = claimSettlementVO.getIntoSettlementList();
        // 汇总
        BigDecimal intoSettlementAmount = com.zatech.cgnci.project.base.utils.BeanUtils.sumBigDecimalProperty(intoSettlementList, CgnciClaimSettlementVO.ReinsurerVO::getTotalSettlementAmount);


        List<CgnciClaimSettlementVO.ReinsurerVO> spreadBackSettlementList = claimSettlementVO.getSpreadBackSettlementList();
        // 汇总
        BigDecimal spreadBackSettlementAmount = com.zatech.cgnci.project.base.utils.BeanUtils.sumBigDecimalProperty(spreadBackSettlementList, CgnciClaimSettlementVO.ReinsurerVO::getTotalSettlementAmount);

        if (spreadBackSettlementAmount.compareTo(intoSettlementAmount) > 0) {
            // 险种-标的-金额类型的合计转分摊回金额不得大于分入金额   标的{标的名称}-险种{险种}的转分摊回金额大于分入计算金额，请修改。
            String msg = "分出摊回总金额大于分入结算总金额，请修改后再提交";
            saveMessage(AlertInfoTypeEnum.ERROR, caseNo, msg, businessSceneType);
            throw new GlobalException(ResponseCodeEnum.HTTP_REQUEST_SERVICE_ERROR, msg);
        }
        if (false) {
            // 险种-标的存在转分分出时，提示再保接受人提示需要填写   再保接受人{再保接受人}转分摊回信息未录入，是否继续提交？
            String msg = String.format("再保接受人%s转分摊回信息未录入，是否继续提交？", "");
            saveMessage(AlertInfoTypeEnum.WARNING, caseNo, msg, businessSceneType);
            noticeList.add(msg);
        }
        if (false) {
            // 险种-标的存在转分分出时，提示对应的再保接受人下的对应险种-标的提示需要填写  再保接受人{再保接受人}下标的{标的名称}-险种{险种}的转分摊回信息未录入，是否继续提交？
            String msg = String.format("再保接受人%s下标的%s-险种%s的转分摊回信息未录入，是否继续提交？", "", "");
            noticeList.add(msg);
            saveMessage(AlertInfoTypeEnum.WARNING, caseNo, msg, businessSceneType);
        }
        resultVO.setConfirmMessageList(noticeList);
        return resultVO;
    }

    private CgnciClaimSettlementResultVO firstSubmit(UserEntity user, CgnciClaimSettlementSubmitDTO req,
                                                     CgnciClaimSettlementResultVO resultVO) {
        CgnciClaimCaseTaskDO caseTask;
        String caseNo = req.getCaseNo();
        String msg = null;
        if (StringUtils.isNotBlank(resultVO.getRemarks())) {
            msg = resultVO.getRemarks();
        }
        String settlementNo = req.getSettlementNo();
        if (ClaimTaskTypeEnum.PREPAY.getCode().equals(req.getTaskType())) {
            caseTask = copyCreateCaseTask(user, caseNo, settlementNo, ClaimTaskTypeEnum.PREPAY.getCode());
            createCaseFlow(user, caseTask, ClaimFlowEnum.CLAIM_PREPAY.getCode());
            saveLog(caseNo, OperationTypeEnum.SUBMIT_PREPAY, user.getUsername(), msg);
        } else if (ClaimTaskTypeEnum.CLOSE.getCode().equals(req.getTaskType())) {
            caseTask = copyCreateCaseTask(user, caseNo, settlementNo, ClaimTaskTypeEnum.CLOSE.getCode());
            createCaseFlow(user, caseTask, ClaimFlowEnum.CLAIM_SETTLEMENT.getCode());
            saveLog(caseNo, OperationTypeEnum.SUBMIT_CASE_FINAL, user.getUsername(), msg);
        } else {
            throw new GlobalException(ResponseCodeEnum.PARAMS_ILLEGAL, "结算任务类型错误。" + req.getTaskType());
        }
        CgnciClaimSettlementTaskDO settlementTask = new CgnciClaimSettlementTaskDO();
        settlementTask.setCaseNo(caseNo);
        settlementTask.setSettlementNo(settlementNo);
        settlementTask.setSettlementType(req.getTaskType());
        settlementTask.setTaskNo(caseTask.getTaskNo());
        updateCaseAndSettlementTaskStatus(user, settlementTask, ClaimTaskStatusEnum.CHECKING.getCode(), null, Boolean.TRUE); // 更新任务状态
        FlowTaskSubmitDTO flowTask = new FlowTaskSubmitDTO();
        flowTask.setFormId(caseTask.getTaskNo());
        approvalService.submit(flowTask);
        resultVO.setPolicyNo(caseTask.getPolicyNo());
        resultVO.setCaseNo(caseTask.getCaseNo());
        resultVO.setTaskNo(caseTask.getTaskNo());
        resultVO.setSettlementNo(req.getSettlementNo());
        return resultVO;
    }

    private void createSaveCheck(CgnciClaimSettlementDTO req) {
        textMaxLength(req.getRemarks());
        Assert.hasText(req.getCaseNo(), "案件号必填。");
        Assert.hasText(req.getRateType(), "汇率约定方式必填。");
        List<CgnciClaimSettlementVO.ReinsurerVO> intoList = req.getIntoSettlementList();
        List<CgnciClaimSettlementVO.ReinsurerVO> spreadBackList = req.getSpreadBackSettlementList();
        settlementDetailCheck(intoList);
        settlementDetailCheck(spreadBackList);
    }

    private static void textMaxLength(String text) {
        if (Objects.isNull(text)) return;
        Assert.isTrue(text.length() <= 5000, "限5000字。");
    }

    private static void settlementDetailCheck(List<CgnciClaimSettlementVO.ReinsurerVO> intoList) {
        if (CollectionUtils.isEmpty(intoList)) return;
//        for (CgnciClaimSettlementVO.ReinsurerVO reinsurer : intoList) {
//            Assert.hasText(reinsurer.getReinsurerName(), "再保人必填。");
//            if (CollectionUtils.isEmpty(reinsurer.getDetails())) continue;
//            for (CgnciClaimSettlementVO.DetailVO detail : reinsurer.getDetails()) {
//                Assert.hasText(detail.getRiskType(), "险种必填。");
//                Assert.hasText(detail.getSubjectName(), "标的名称必填。");
//                Assert.hasText(detail.getLayerName(), "层名称必填。");
//                Assert.hasText(detail.getAmountType(), "金额类型必填。");
//                Assert.notNull(detail.getSettlementAmount(), "结算金额（结算币种）必填。");
//            }
//
//        }
    }


}
